﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http.Headers;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using CTP.CRM.Core.Model;
using Serilog;
using CTP.CRM.Core.Logger;

namespace CTP.CRM.Core
{
    public class LogHelper
    {
        private static string _webhook;

        private static string _title = "";

        private static bool _needAtAll = false;

        public static void Init(NoticeOptions options, bool needAtAll)
        {
            _webhook = options.Webhook;
            _title = options.Title;
            _needAtAll = needAtAll;
        }

        public static void Debug(string msg, bool isSendNotice = false, params object[] propertyValues)
        {
            Log.Debug(msg, propertyValues);
            if (isSendNotice)
            {
                SendNotice(msg, MessageType.Debug);
            }
        }

        public static void Error(Exception error, bool isSendNotice = true, params object[] propertyValues)
        {
            Error(error.ToString(), isSendNotice, propertyValues);
        }

        public static void Error(string msg, bool isSendNotice = true, params object[] propertyValues)
        {
            Log.Error(msg, propertyValues);
            if (isSendNotice)
            {
                SendNotice(msg, MessageType.Error);
            }
        }

        public static void Info(string msg, bool isSendNotice = false, params object[] propertyValues)
        {
            Log.Information(msg, propertyValues);
            if (isSendNotice)
            {
                SendNotice(msg, MessageType.Info);
            }
        }

        public static void Warn(string msg, bool isSendNotice = false, params object[] propertyValues)
        {
            Log.Warning(msg, propertyValues);
            if (isSendNotice)
            {
                SendNotice(msg, MessageType.Warn);
            }
        }

        public static async void SendNotice(string message, string webhook, string title = "", MessageType messageType = MessageType.Notice, bool hardSend = false)
        {
            string webhook2 = webhook;
            try
            {
                if (Debugger.IsAttached && !hardSend)
                {
                    Console.WriteLine(Environment.NewLine + "-- 本地开发环境，跳过发送飞书通知逻辑");
                    return;
                }

                if (string.IsNullOrEmpty(webhook2))
                {
                    Console.WriteLine(Environment.NewLine + "-- 未找到配置的webhook地址");
                    return;
                }

                if (webhook2.IndexOf("feishu") <= -1)
                {
                    Console.WriteLine(Environment.NewLine + "-- 暂时只支持飞书通知，当前配置：" + webhook2);
                    return;
                }

                var sendMessage = new
                {
                    msg_type = "post",
                    content = new
                    {
                        post = new
                        {
                            zh_cn = new
                            {
                                title = title + "_" + messageType,
                                content = ((_needAtAll && messageType != MessageType.Notice) ? new List<object>
                            {
                                new List<object>
                                {
                                    new
                                    {
                                        tag = "text",
                                        text = message + Environment.NewLine
                                    },
                                    new
                                    {
                                        tag = "at",
                                        user_id = "all"
                                    }
                                }
                            } : new List<object>
                            {
                                new List<object>
                                {
                                    new
                                    {
                                        tag = "text",
                                        text = message + Environment.NewLine
                                    }
                                }
                            })
                            }
                        }
                    }
                };
                Task.Run(delegate
                {
                    PostAsync<object>(webhook2, JsonConvert.SerializeObject(sendMessage));
                });
            }
            catch (Exception ex)
            {
                Exception e = ex;
                Console.WriteLine($"{Environment.NewLine}通知发送失败！{e}");
            }
        }

        public static void SendNotice(string message, MessageType messageType = MessageType.Notice, bool hardSend = false)
        {
            if (string.IsNullOrEmpty(_webhook))
            {
                Console.WriteLine(Environment.NewLine + "-- 未找到配置的webhook地址");
            }
            else
            {
                SendNotice(message, _webhook, _title, messageType, hardSend);
            }
        }

        public static void SendNotice(string message, string wbeHook)
        {
            if (string.IsNullOrEmpty(wbeHook))
            {
                throw new NullReferenceException("wbeHok参数不能为空");
            }

            SendNotice(message, wbeHook, _title, MessageType.Notice, hardSend: true);
        }

        private static async Task<T> PostAsync<T>(string url, string postData = null, string contentType = null, int timeOut = 30, Dictionary<string, string> headers = null, bool ignoreStatusCodeCheck = false) where T : new()
        {
            try
            {
                postData = postData ?? "";
                using HttpClient client = new HttpClient();
                client.Timeout = new TimeSpan(0, 0, timeOut);
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }

                using HttpContent httpContent = new StringContent(postData, Encoding.UTF8);
                if (contentType != null)
                {
                    httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                }
                else
                {
                    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                }

                HttpResponseMessage response = await client.PostAsync(url, httpContent);
                if (!ignoreStatusCodeCheck && response.StatusCode != HttpStatusCode.OK)
                {
                    Console.WriteLine($"{Environment.NewLine}发送飞书通知返回异常状态码：{response.StatusCode}，请求参数：{postData}");
                    throw new Exception($"飞书通知返回状态码异常！当前返回状态码：{response.StatusCode}");
                }

                return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
            }
            catch (Exception ex2)
            {
                Exception ex = ex2;
                throw new Exception($"返回参数序列化失败，异常信息{ex}！");
            }
        }
    }
}
